#coding:utf-8


import wx
import wx.lib.platebtn as platebtn
import wx.lib.buttons  as  buttons
import wx.lib.buttonpanel as bp

import wx.grid as grid
import wx.lib.scrolledpanel as scrolled
import os, sys

# Sizer
class Sizer(wx.BoxSizer):
    def __init__(self, orient=wx.HORIZONTAL, flag=0, border=0):
        wx.BoxSizer.__init__(self, orient)
        self.flag = flag
        self.border = border
        
    def Add(self, item, **kwargs):
        super(Sizer, self).Add(item, kwargs.get('proportion',0),
                               kwargs.get('flag',self.flag),
                               kwargs.get('border',self.border))
        
    def Attach(self, *items, **kwargs):
        for item in items:
            self.Add(item, **kwargs)
        
    def Insert(self, index, item, **kw):
        super(Sizer, self).Insert(index, item, kw.get('proportion',0),
                                    kw.get('flag', self.flag),
                                    kw.get('border', self.border),
                                    kw.get('userData', None))
  
# TextCtrl          
class CustomTextLabel(wx.Window):
    def __init__(self, parent, label = ""):
        wx.Window.__init__(self, parent)
        self.label = label
        self.font = Font(9, bold = False)
        self._height = 4
        self.fontColor = wx.BLACK
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        
    def SetFont(self, *args, **kw):
        
        self.fontColor = kw.get("fontColor", self.fontColor)
        self.font = Font(*args)
        self.SetSize((-1, args[0]*2))
        self._height = (self.GetClientRect().height - args[0]) / 2
        
    def SetLabel(self, label):
        self.label = label
        
    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        rect = self.GetClientRect()
        #gc.SetBrush(wx.Brush(wx.Color(240,240,240)))
        #gc.SetPen(wx.Pen(self.fontColor))
        #gc.DrawRectangle(1, 1, rect.width-2, rect.height-2)
        
        gc.SetFont(self.font ,self.fontColor)
        gc.DrawText(self.label, 3, self._height)
        evt.Skip()
        
        
class TitleTextLabel(CustomTextLabel):
    def __init__(self, parent, title, label = ""):
        CustomTextLabel.__init__(self, parent)
        self.title = title
        self.SetFont(11)
        self.SetLabel(label)
        
    def SetLabel(self, label):
        super(TitleTextLabel, self).SetLabel("%s %s"%(self.title, label))

class Font(wx.Font):
    def __init__(self, size, bold = False):
        if bold:
            wx.Font.__init__(self, size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
        else:
            wx.Font.__init__(self, size, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)



class Panel(wx.Panel):
    def __init__(self, parent, *args, **kw):
        wx.Panel.__init__(self, parent, *args, **kw)
        self.Bind(wx.EVT_PAINT, self._OnPaint)
        
    def _OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        col2 = wx.Color(200,200,200)
        col1 = wx.Color(170,160,160)
        rect = self.GetClientRect()
        grad = gc.CreateLinearGradientBrush(0, 1, 0, rect.height - 1, col2, col1)
        gc.SetBrush(grad)
        gc.DrawRectangle(0, 0, rect.width - 0.5, rect.height - 0.5)
        dc.SetPen(wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DDKSHADOW), 1))
        dc.DrawLine(0, 0, 0, rect.height)
        dc.DrawLine(rect.width-1, 0, rect.width-1, rect.height)
        evt.Skip()
        
class OperationPanel(wx.ToolBar):
    '''bitmap, checkstyle, label, event'''
    def __init__(self, parent, text):
        wx.ToolBar.__init__(self, parent, style=wx.TB_FLAT|wx.TB_HORIZONTAL)
        
    def layout(self, items):
        self.createButtons(items)
        self.Realize()
        
    def createButtons(self, items):
        for item in items:
            if not item:
                self.AddSeparator()
            else:
                _id = wx.NewId()
                btn = self.AddSimpleTool(_id, item[0], shortHelpString = item[2], isToggle=item[1] )
                self.Bind(wx.EVT_TOOL, item[3], id = _id)
        

class OperationPanel1(bp.ButtonPanel):
    def __init__(self, parent, text, *args, **kw):
        bp.ButtonPanel.__init__(self, parent, -1, text, style = bp.BP_USE_GRADIENT, *args, **kw)
        
    def layout(self, items):
        self.Freeze()
        buttons = self.createButtons(items)
        self.setStyle()
        self.Thaw()
        self.DoLayout()
        return buttons
        
    def createButtons(self, items):
        buttons = []
        for item in items:
            if not item:
                self.AddSeparator()
            else:
                btn = bp.ButtonInfo(self, wx.NewId(), item[0], kind=item[1], shortHelp =item[2])
                btn.SetTextAlignment(bp.BP_BUTTONTEXT_ALIGN_RIGHT)
                self.Bind(wx.EVT_BUTTON, item[3], btn)
                self.AddButton(btn)
                buttons.append(btn)
        return buttons
            
    def setStyle(self):
        self.SetAlignment(bp.BP_ALIGN_RIGHT)
        bp_art = self.GetBPArt()
        bp_art.SetColor(bp.BP_BORDER_COLOR, wx.Color(50,50,50))
        bp_art.SetMetric(bp.BP_BORDER_SIZE, 1)
        bp_art.SetMetric(bp.BP_PADDING_SIZE, wx.Size(4,0))
        
        bp_art.SetGradientType(bp.BP_GRADIENT_HORIZONTAL)
        bp_art.SetColor(bp.BP_GRADIENT_COLOR_FROM, wx.Color(190, 190, 190))
        bp_art.SetColor(bp.BP_GRADIENT_COLOR_TO, wx.Color(230, 230, 230))
        bp_art.SetColor(bp.BP_SEPARATOR_COLOR, wx.Color(100,100,100))
        bp_art.SetColor(bp.BP_SELECTION_PEN_COLOR, wx.Color(180, 200, 250))
        bp_art.SetColor(bp.BP_SELECTION_BRUSH_COLOR, wx.Color(180, 200, 250))
        
        
class CustomFrameMixin:
    def _initFrameEvent(self):
        self.Bind(wx.EVT_LEFT_DOWN, self._OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self._OnLeftUp)
        self.Bind(wx.EVT_MOTION, self._OnMouseMove)
        self.Bind(wx.EVT_PAINT, self._OnPaint)
    
    def _OnLeftDown(self, evt):
        x, y = self.ClientToScreen(evt.GetPosition())
        originx, originy = self.GetPosition()
        self.space = (x - originx, y - originy)
        self.CaptureMouse()
        
    def _OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()
        self.Move(self.GetPosition())
            
    def _OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown() and self.HasCapture():
            x, y = self.ClientToScreen(evt.GetPosition())
            fp = (x - self.space[0], y - self.space[1])
            self.Move(fp)
            
    def _OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        col1 = wx.Color(30,70,140)
        col2 = wx.Color(200,200,200)
        rect = self.GetClientRect()
        grad = gc.CreateLinearGradientBrush(0, 20, rect.width, 20, col1, col2)
        gc.SetBrush(grad)
        
        #gc.SetPen(gc.CreatePen(wx.Pen(self._color_face, 1)))
        gc.DrawRectangle(0, 0, rect.width - 0, rect.height - 0)
        
        #dc.SetPen(wx.Pen(self._color_shadow, 1))
        #dc.DrawLine(3, 3, rect.width - 5, 3)
        #dc.DrawLine(4, 3, 4, rect.height - 5)
        #dc.DrawLine(rect.width - 5, 3, rect.width - 5, rect.height - 4)
        
        #dc.SetPen(wx.Pen(self._color_shadow, 1))
        #dc.DrawLine(rect.width -0.5, 0, rect.width -0.5, rect.height)
        #dc.DrawLine(0, rect.height -0.5, rect.width, rect.height - 0.5)
        
        gc.SetFont(Font(9, bold = True) ,wx.WHITE)
        gc.DrawText(self.caption,10,1)
        evt.Skip()

ADDR_GENERAL = '/ico/user/general/'
class CustomFrame(wx.Frame, CustomFrameMixin):
    def __init__(self, parent, caption):
        wx.Frame.__init__(self, parent, style = wx.FRAME_SHAPED, title = caption)
        self.caption = caption
        
        sizer = Sizer(wx.HORIZONTAL, flag = wx.ALL, border = 1)
        self.buttonboxes = OperationPanel(self, '')
        
        items = [
                #(envs.server_path+ADDR_GENERAL+'f_minimize', wx.ITEM_NORMAL, '最小化', self.OnMinimize),
                #None,
                (envs.server_path+ADDR_GENERAL+'f_staytop', wx.ITEM_CHECK, u'置于最前', self.OnStayTop),
                #None,
                (envs.server_path+ADDR_GENERAL+'f_close', wx.ITEM_NORMAL, u'关闭', self.OnClose),
                ]
        buttons = self.buttonboxes.layout(items)
        
        sizer.Add((0,0), proportion = 1)
        sizer.Add(self.buttonboxes)
        self.mainsizer = Sizer(wx.VERTICAL, flag = wx.EXPAND)
        self.mainsizer.Add(sizer)
        self.SetSizer(self.mainsizer)
        self.Fit()
        
        self.OnStayTop(None)
        buttons[1].SetToggled(True)
        self._initFrameEvent()
        
    def OnStayTop(self, evt):
        style = self.GetWindowStyle()
        if style&wx.STAY_ON_TOP == wx.STAY_ON_TOP:
            self.SetWindowStyle(style&(~wx.STAY_ON_TOP))
        else:
            self.SetWindowStyle(style|wx.STAY_ON_TOP)
         
    def OnMinimize(self, evt):
        print self.buttonboxes.GetControls()
        print self.buttonboxes.GetChildren()
        
    def OnClose(self, evt):
        self.Hide()


class CustomBitmapButton(buttons.GenBitmapButton):
    def __init__(self, parent, bmp = None):
        buttons.GenBitmapButton.__init__(self, parent, -1, bmp,
                                      style = wx.BORDER_NONE)
        #self.SetBackgroundColour(wx.WHITE)

class CustomInputCtrl(wx.PyWindow):
    def __init__(self, parent, value, style = 0, *args, **kw):
        wx.PyWindow.__init__(self, parent, *args, **kw)
        #self.SetBackgroundColour(wx.WHITE)
        self.SetMinSize((120,20))
        self.value = str(value)
        editor = wx.TextCtrl(self, -1, style = style|wx.BORDER_SIMPLE)
        editor.SetBackgroundColour(wx.Colour(255,255,200))
        editor.SetForegroundColour(wx.Colour(0,0,0))
        editor.Hide()
        self.col = wx.Color(140,50,90)
        self.editor = editor
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        #self.Bind(wx.EVT_SIZE, lambda evt: self.Refresh())
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.editor.Bind(wx.EVT_KILL_FOCUS, self.CloseEditor)
        
    def __del__(self):
        print 'del custom input ctrl.'
    
    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        rect = self.GetClientRect()
        gc.SetBrush(wx.Brush(wx.Color(240,240,240)))
        gc.SetPen(wx.Pen(wx.BLACK))
        gc.DrawRectangle(1, 1, rect.width-2, rect.height-2)
        
        gc.SetFont(Font(9, bold = False) ,wx.BLACK)
        gc.DrawText(self.value, 3, 3)
        evt.Skip()
        
    def OnLeftDown(self, evt=None):
        if self.editor.IsShown():
            return
        
        x, y = self.GetPosition()
        width, height = self.GetSize()
        
        editor = self.editor
        editor.SetDimensions(0, 0, width, height)
        editor.SetValue(self.value) 
        editor.Show()
        editor.Raise()
        editor.SetFocus()
        
    def CloseEditor(self, evt=None):
        if not self.editor.IsShown():
            return
        self.value = self.editor.GetValue()
        self.editor.Hide()
        self.SetFocus()
        self.Refresh()
        
    def GetValue(self):
        return self.value.strip()
    
    def SetValue(self, value):
        self.value = value
        

'''
class PlotPanel(wxmpl.PlotPanel):
    def __init__(self, parent):
        wxmpl.PlotPanel.__init__(self, parent, -1, cursor = False, 
                                    crosshairs = False, location = False)
        self.fig = self.get_figure()
        self.axes = self.fig.gca()
        
    
    def set_data(self, xlist, ylist, **kw):
        self.axes.cla()
        self.axes.plot(xlist,ylist, **kw)
        
    def set_xlabel(self, xlabel):
        self.axes.set_xlabel(xlabel)
        
    def set_ylabel(self, ylabel):
        self.axes.set_ylabel(ylabel)
        
    def set_labels(self, xlabel, ylabel):
        self.set_xlabel(xlabel)
        self.set_ylabel(ylabel)

'''

class DataPanel(grid.Grid):
    def __init__(self, parent, colLabels, width = 500):
        grid.Grid.__init__(self, parent)
        self.CreateGrid(0, len(colLabels))
        #初始化列标题
        self.SetLabelBackgroundColour(wx.WHITE)
        self.SetLabelFont(Font(9, bold = True))

        attr = grid.GridCellAttr()
        attr.SetReadOnly()
        for index in range(len(colLabels)):
            self.SetColLabelValue(index, colLabels[index])
            self.SetColAttr(index, attr)
        self.current_row = -1
        
        #初始化行列样式
        self.SetColLabelSize(17)
        self.SetRowLabelSize(20)
        
        #初始化行列大小
        #self.SetDefaultRowSize(20)
        
        #禁止拖动改变行高
        #self.DisableDragRowSize()
        
    def newLine(self):
        self.AppendRows(1)
        self.current_row += 1
        
    def writeData(self, index, value):
        self.SetCellValue(self.current_row, index, str(value))
        
    def write(self, dataList):
        length = len(dataList)
        assert length <= self.GetNumberCols(), u"数据个数不该大于列个数"
        for i in range(length):
            self.writeData(i, dataList[i])
            

class CustomContainer(scrolled.ScrolledPanel):
    def __init__(self, *args, **kw):
        scrolled.ScrolledPanel.__init__(self, *args, **kw)
        self.SetBackgroundColour(wx.WHITE)
        
        self.mainsizer = Sizer(orient = wx.VERTICAL, flag = wx.ALL|wx.EXPAND, border = 10)
        self.SetSizer(self.mainsizer)
        self.Fit()
        
        self.SetupScrolling()
        
    def Add(self, control):
        self.mainsizer.Add(control)
        self.SetupScrolling()
        
    def Attach(self, *controls):
        self.mainsizer.Attach(*controls)
        self.SetupScrolling()
        
    def AddSpacer(self, height):
        self.mainsizer.Add((-1, height))
        self.SetupScrolling()
        
class OpenDialog(wx.FileDialog):
    def __init__(self, parent, wildcard, defaultDir = u""):
        wx.FileDialog.__init__(self, parent, defaultDir=defaultDir, message = u"打开文件",
                               wildcard=wildcard, style= wx.FD_OPEN)
            
            
class SaveDialog(wx.FileDialog):
    def __init__(self, parent, wildcard, defaultDir = u"", defaultFile = u""):
        wx.FileDialog.__init__(self, parent, defaultDir=defaultDir, 
                               message = u"保存文件", wildcard=wildcard, defaultFile = defaultFile,
                               style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
   
   
FILTER_TESTCASE = u"测试用例集(*.test)|*.test|All files (*.*)|*.*"
DEFAULTDIR_TESTCASE = u'script'      
class TestCaseOpenDialog(OpenDialog):
    def __init__(self, parent, defaultFile = ""):
        OpenDialog.__init__(self, parent, FILTER_TESTCASE, DEFAULTDIR_TESTCASE)
        
class TestCaseSaveDialog(SaveDialog):
    def __init__(self, parent, defaultFile = ""):
        SaveDialog.__init__(self, parent, FILTER_TESTCASE, DEFAULTDIR_TESTCASE, defaultFile)
        
class AskingDialog(wx.MessageDialog):
    def __init__(self, parent, message):
        wx.MessageDialog.__init__(self, parent, message, u'Are you sure?',
                                  wx.OK | wx.CANCEL | wx.ICON_QUESTION)
        
class WarningDialog(wx.MessageDialog):
    def __init__(self, parent, message):
        wx.MessageDialog.__init__(self, parent, message, u'warning!',
                                  wx.OK | wx.ICON_WARNING)     
        
import  wx.gizmos   as  gizmos
class Timer(wx.Window):
    cnt = 0
    def __init__(self, parent):
        wx.Window.__init__(self, parent)
        self.SetInitialSize((90,30))
        self.clock = gizmos.LEDNumberCtrl(self,pos=(0,0),size=(90,30))
        self.clock.SetAlignment(gizmos.LED_ALIGN_RIGHT)
        self.timer = wx.Timer(self)
        
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        
    def OnTimer(self, evt):
        self.cnt += 1
        self.clock.SetValue(str(self.cnt))
        
    def start(self):
        self.timer.Start(1000)
        
    def stop(self):
        self.timer.Stop()
        
class TransBitmap(wx.PyControl):
    def __init__(self, parent, bmp = None , pos=wx.DefaultPosition, size=wx.DefaultSize,):
        wx.PyControl.__init__(self, parent, -1, pos, size,
                              wx.BORDER_NONE|wx.TRANSPARENT_WINDOW)
        self.SetBackgroundColour(wx.WHITE)
        if bmp:
            self.SetBitmap(bmp)
        else:
            self.ClearBitmap()
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        
    def SetBitmap(self, bmp):
        self.bmp = bmp
        self.Refresh()
        
    def ClearBitmap(self):
        self.SetBitmap(wx.EmptyBitmapRGBA(16, 16, 255, 255, 255))
        
        
    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0)

        

class ProgressBar(wx.PyControl):
    def __init__(self, parent, *args, **kw):
        wx.PyControl.__init__(self, parent, *args, **kw)
        self.SetBackgroundColour(wx.WHITE)
        self.max, self.value = 100, 0
        
        self.forecolor = wx.Color(200, 200, 240)
        self.tmr = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTimer)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, lambda evt: self.Refresh())
        
    def Start(self):
        if not self.tmr.IsRunning():
            self.tmr.Start(1000)
        
    def Stop(self):
        if self.tmr.IsRunning():
            self.tmr.Stop()
        
    def SetRange(self, max):
        self.max = max
        self.Refresh()
        
    def SetValue(self, value):
        self.value = value
        self.Refresh()
        
    def OnPaint(self, evt):
        dc = wx.PaintDC(self)
        gc = wx.GraphicsContext.Create(dc)
        rect = self.GetClientRect()
        _part = rect.width / float(self.max)
        gc.SetBrush(wx.Brush(self.forecolor))
        gc.DrawRectangle(0, 0, self.value * _part, rect.height)
        gc.SetFont(Font(9) ,wx.BLACK)
        gc.DrawText("%s/%s"%(self.value, self.max), rect.width/2, 1)
        evt.Skip()
        
    def OnTimer(self, evt):
        if self.value < self.max:
            self.value += 1
            self.Refresh()

        


        
if __name__ == '__main__':
    app=wx.App(0)
    f = wx.Frame(None)
    
    f.x = ProgressBar(f)
    #f.x.Start()
    #f.x = TransText(f, "23333333")
    f.Show()
    app.MainLoop()